---
title: Physics
slug: /physics
section: Physics
---

import PhysicsExample from '!!raw-loader!./examples/physics.ts';

Excalibur comes built in with two physics simulations. 

- "Arcade" style physics which is good for basic collision detection for non-rotated rectangular areas.
  - Example: platformers, tile based games, top down, etc
- "Realistic" style physics which is good for rigid body games where realistic collisions are desired
  - Example: block stacking, angry bird's style games, etc

**Limitations**

> **_Note:_**  The `SolverStrategy.Arcade` does not support `body.friction`.

## Arcade

Arcade physics simulation is on by default, but can be enabled explicitly in the `Engine` constructor.

```typescript
const game = new Engine({
  physics: {
    solver: SolverStrategy.Arcade
  },
  ...
});
```

## Realistic

Realistic physics are not on by default, but can be enabled explicitly in the `Engine` constructor.

```typescript
const game = new Engine({
  physics: {
    solver: SolverStrategy.Realistic
  },
  ...
});
```

### Example

<PlaygroundEmbed 
  title="Physics"
  code={PhysicsExample} 
/>

## Other Physics Settings

See [[PhysicsConfig]] documentation for more

- Turn off excalibur physics [[PhysicsConfig.enabled]]
- Global acceleration applied to [[CollisionType.Active|active objects]] with [[PhysicsConfig.gravity]]
- Configure Fast moving object detection (continuous collision) [[PhysicsConfig.continuous]]
- Physics realistic passes, more passes mean higher quality simulation at the expense of cpu
  - Realistic solver position iterations, improves overlap resolution [[PhysicsConfig.realistic|PhysicsConfig.realistic.positionIterations]]
  - Realistic solver velocity iterations, improves response and stability [[PhysicsConfig.realistic|PhysicsConfig.realistic.velocityIterations]]

## Using Physics with Actors or Entities

The physics simulation has 2 major pieces for actors

1. [[BodyComponent]] - Controls the motion and qualities of the physics simulation
2. [[ColliderComponent]] - Stores the geometry of any collider and performs overlap testing

### Actors

Actors come out of the box with both of these components, an implicitly created [[BodyComponent]] and a [[ColliderComponent]]
of a [[PolygonCollider|box]] that matches the specified `width` and `height`, or a [[CircleCollider|circle]]

```typescript
const actor = new ex.Actor({
  pos: ex.vec(200, 200),
  width: 100,
  height: 100,
  collisionType: ex.CollisionType.Active,
})

const builtInBox = actor.collider.get()
```

### Entities

Reminder entities don't have anything pre-built, all Actors are Entities, but with the common built in features included.

```typescript
const entity = new ex.Entity([
  new TransformComponent(),
  new BodyComponent(),
  new ColliderComponent(),
])

const tx = entity.get(TransformComponent)

const body = entity.get(BodyComponent)

const collider = entity.get(ColliderComponent)
```

## Collision System Under the Hood

Under the hood excalibur does a broadphase/narrowphase approach to locating and resolving collisions.

1. Broadphase is run against a dynamic tree spatial data structure to locate potential collision pairs
2. Narrowphase is run to find any actual overlapping colliders
3. The collision solver is run (Arcade or Realistic). Collisions are resolved according to the configured solver, either Arcade which does axis aligned resolution, or realistic which attempts to do a force based resolution.

    a. `precollision` events are fired on Entities just before collision resolution, you have an opportunity to call [[CollisionContact.cancel]] and stop the collision at this time.

    b. `postcollision`events are fire after resolution.

    c. `collisionstart` events fire when two colliders first touch, and does not fire in subsequent frames until they separate.

    d. `collisionend` events fire when two colliders separate, and does not fire in subsequent frames until they touch again.

## Example Active-Active/Active-Fixed scenario

```ts
// setup game
const game = new ex.Engine({
  width: 600,
  height: 400,
  physics: {
    // use rigid body realistic
    solver: ex.SolverStrategy.Realistic,

    // set global acceleration simulating gravity pointing down
    gravity: ex.vec(0, 700)
  }
});
const block = new ex.Actor({
  pos: new ex.Vector(300, 0),
  width: 20,
  height: 20,
  color: ex.Color.Blue
});
block.body.useBoxCollider(); // useBoxCollision is the default, technically optional
block.body.collider.type = ex.CollisionType.Active;
game.add(block);

const circle = new ex.Actor({
  x: 301,
  y: 100,
  width: 20,
  height: 20,
  color: ex.Color.Red
});
circle.body.useCircleCollider(10);
circle.body.collider.type = ex.CollisionType.Active;
game.add(circle);

const ground = new ex.Actor({
  x: 300,
  y: 380,
  width: 600,
  height: 10,
  color: ex.Color.Black;
});

ground.body.useBoxCollider(); // optional
ground.body.collider.type = ex.CollisionType.Fixed;

game.add(ground);
// start the game

game.start();
```
